1
2
3
4 package joeq.Compiler.Quad;
5
6 import joeq.Class.jq_Method;
7 import joeq.Class.jq_Primitive;
8 import joeq.Compiler.Quad.Operand.RegisterOperand;
9 import joeq.Compiler.Quad.Operator.Special;
10 import joeq.Compiler.Quad.Operator.Unary;
11 import joeq.Memory.Address;
12 import joeq.Memory.CodeAddress;
13 import joeq.Memory.StackAddress;
14 import joeq.Runtime.Unsafe;
15 import joeq.Scheduler.jq_Thread;
16 import jwutil.util.Assert;
17
18
19
20
21
22 class B2QUnsafeHandler implements BytecodeToQuad.UnsafeHelper {
23 public boolean isUnsafe(jq_Method m) {
24 return m.getDeclaringClass() == Unsafe._class;
25 }
26 public boolean endsBB(jq_Method m) {
27 return m == Unsafe._longJump;
28 }
29 public boolean handleMethod(BytecodeToQuad b2q, ControlFlowGraph quad_cfg, BytecodeToQuad.AbstractState current_state, jq_Method m, Operator.Invoke oper) {
30 Quad q;
31 if (m == Unsafe._floatToIntBits) {
32 Operand op = current_state.pop_F();
33 RegisterOperand res = b2q.getStackRegister(jq_Primitive.INT);
34 q = Unary.create(quad_cfg.getNewQuadID(), Unary.FLOAT_2INTBITS.INSTANCE, res, op);
35 current_state.push_I(res.copy());
36 } else if (m == Unsafe._intBitsToFloat) {
37 Operand op = current_state.pop_I();
38 RegisterOperand res = b2q.getStackRegister(jq_Primitive.FLOAT);
39 q = Unary.create(quad_cfg.getNewQuadID(), Unary.INTBITS_2FLOAT.INSTANCE, res, op);
40 current_state.push_F(res.copy());
41 } else if (m == Unsafe._doubleToLongBits) {
42 Operand op = current_state.pop_D();
43 RegisterOperand res = b2q.getStackRegister(jq_Primitive.LONG);
44 q = Unary.create(quad_cfg.getNewQuadID(), Unary.DOUBLE_2LONGBITS.INSTANCE, res, op);
45 current_state.push_L(res.copy());
46 } else if (m == Unsafe._longBitsToDouble) {
47 Operand op = current_state.pop_L();
48 RegisterOperand res = b2q.getStackRegister(jq_Primitive.DOUBLE);
49 q = Unary.create(quad_cfg.getNewQuadID(), Unary.LONGBITS_2DOUBLE.INSTANCE, res, op);
50 current_state.push_D(res.copy());
51 } else if (m == Unsafe._getThreadBlock) {
52 RegisterOperand res = b2q.getStackRegister(jq_Thread._class);
53 q = Special.create(quad_cfg.getNewQuadID(), Special.GET_THREAD_BLOCK.INSTANCE, res);
54 current_state.push_A(res.copy());
55 } else if (m == Unsafe._setThreadBlock) {
56 Operand loc = current_state.pop_A();
57 q = Special.create(quad_cfg.getNewQuadID(), Special.SET_THREAD_BLOCK.INSTANCE, loc);
58 } else if (m == Unsafe._longJump) {
59 Operand eax = current_state.pop_I();
60 Operand sp = current_state.pop(StackAddress._class);
61 Operand fp = current_state.pop(StackAddress._class);
62 Operand ip = current_state.pop(CodeAddress._class);
63 q = Special.create(quad_cfg.getNewQuadID(), Special.LONG_JUMP.INSTANCE, ip, fp, sp, eax);
64 } else if (m == Unsafe._popFP32) {
65 RegisterOperand res = b2q.getStackRegister(jq_Primitive.FLOAT);
66 q = Special.create(quad_cfg.getNewQuadID(), Special.POP_FP32.INSTANCE, res);
67 current_state.push_F(res.copy());
68 } else if (m == Unsafe._popFP64) {
69 RegisterOperand res = b2q.getStackRegister(jq_Primitive.DOUBLE);
70 q = Special.create(quad_cfg.getNewQuadID(), Special.POP_FP64.INSTANCE, res);
71 current_state.push_D(res.copy());
72 } else if (m == Unsafe._pushFP32) {
73 Operand val = current_state.pop_F();
74 q = Special.create(quad_cfg.getNewQuadID(), Special.PUSH_FP32.INSTANCE, val);
75 } else if (m == Unsafe._pushFP64) {
76 Operand val = current_state.pop_D();
77 q = Special.create(quad_cfg.getNewQuadID(), Special.PUSH_FP64.INSTANCE, val);
78 } else if (m == Unsafe._EAX) {
79 RegisterOperand res = b2q.getStackRegister(jq_Primitive.INT);
80 q = Special.create(quad_cfg.getNewQuadID(), Special.GET_EAX.INSTANCE, res);
81 current_state.push_I(res.copy());
82 } else if (m == Unsafe._pushArg) {
83 Operand val = current_state.pop_I();
84 q = Special.create(quad_cfg.getNewQuadID(), Special.PUSHARG_I.INSTANCE, val);
85 } else if (m == Unsafe._pushArgA) {
86 Operand val = current_state.pop_P();
87 q = Special.create(quad_cfg.getNewQuadID(), Special.PUSHARG_P.INSTANCE, val);
88 } else if (m == Unsafe._invoke) {
89 Operand loc = current_state.pop_P();
90 RegisterOperand res = b2q.getStackRegister(jq_Primitive.LONG);
91 q = Special.create(quad_cfg.getNewQuadID(), Special.INVOKE_L.INSTANCE, res, loc);
92 current_state.push_L(res.copy());
93 } else if (m == Unsafe._invokeA) {
94 Operand loc = current_state.pop_P();
95 RegisterOperand res = b2q.getStackRegister(Address._class);
96 q = Special.create(quad_cfg.getNewQuadID(), Special.INVOKE_P.INSTANCE, res, loc);
97 current_state.push_P(res.copy());
98 } else if (m == Unsafe._isEQ) {
99 RegisterOperand res = b2q.getStackRegister(jq_Primitive.BOOLEAN);
100 q = Special.create(quad_cfg.getNewQuadID(), Special.ISEQ.INSTANCE, res);
101 current_state.push_I(res.copy());
102 } else if (m == Unsafe._isGE) {
103 RegisterOperand res = b2q.getStackRegister(jq_Primitive.BOOLEAN);
104 q = Special.create(quad_cfg.getNewQuadID(), Special.ISGE.INSTANCE, res);
105 current_state.push_I(res.copy());
106 } else {
107 System.err.println(m.toString());
108 Assert.UNREACHABLE();
109 return false;
110 }
111 b2q.appendQuad(q);
112 return true;
113 }
114 }